package com.ocom.xfrecode.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ocom.common.entity.card.EntityXfGoodListOrg;
import com.ocom.common.enums.ConsStateEnum;
import com.ocom.common.enums.OpTypeDiffEnum;
import com.ocom.common.enums.OpTypeEnum;
import com.ocom.common.request.payconfig.mealorder.RefundOrderDishesRequest;
import com.ocom.common.request.ugcapi.OrderedShowRequest;
import com.ocom.common.request.xfrecde.*;
import com.ocom.common.resp.Result;
import com.ocom.common.utils.DateUtils;
import com.ocom.common.utils.ResultUtil;
import com.ocom.common.vo.xfrecode.*;
import com.ocom.xfrecode.mapper.XfGoodListOrgMapper;
import com.ocom.xfrecode.service.XfGoodListOrgService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.awt.font.TextHitInfo;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class XfGoodListOrgServiceImpl extends ServiceImpl<XfGoodListOrgMapper, EntityXfGoodListOrg> implements XfGoodListOrgService {

    @Autowired
    private XfGoodListOrgMapper xfGoodListOrgMapper;

    @Override
    public Boolean sveXfGoodList(EntityXfGoodListOrg entityXfGoodListOrg) {
        return this.save(entityXfGoodListOrg);
    }

    @Override
    public Boolean saveXfGoodListBatch(List<EntityXfGoodListOrg> list) {
        return this.saveBatch(list);
    }

    @Override
    public List<EntityXfGoodListOrg> getXfGoodList(GetXfGoodListRequest request) {
        QueryWrapper<EntityXfGoodListOrg> queryWrapper= new QueryWrapper<>();
        queryWrapper.eq("com_id",request.getComId());
        queryWrapper.eq("order_no",request.getOrderNo());
        queryWrapper.eq("month_value",request.getMonthValue());
        return this.list(queryWrapper);
    }

    @Override
    public Boolean refundXfGoodList(RefundOrderDishesRequest request) {
        UpdateWrapper<EntityXfGoodListOrg> queryWrapper= new UpdateWrapper<>();
        queryWrapper.eq("com_id",request.getComId());
        queryWrapper.eq("order_no",request.getOrderNo());
        queryWrapper.eq("month_value",request.getMonthValue());
        if(ObjectUtil.isNotEmpty(request.getGoodsId())){
            queryWrapper.in("dishes_id",request.getGoodsId());
        }
        queryWrapper.set("if_refund",1);
        return this.update(queryWrapper);
    }

    @Override
    public List<EntityXfGoodListOrg> getOrderDishesDetail(OrderedShowRequest request) {
        return null;
    }

    @Override
    public List<DishesIdNumVo> getXfGoodListByPointId(XfGoodListByPointIdRequest request) {
        QueryWrapper<EntityXfGoodListOrg> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("dishes_id",
                "sum(weight_number) as weight_number");

        String month1 = request.getMealDate().replace("-","").substring(0,6);
        String month2 = DateUtils.getLastMonth(month1, 1);

        //日期范围查询
        queryWrapper.and(wrapper -> {
            wrapper.or().eq("month_value",month1).or().eq("month_value",month2);
        });
        queryWrapper.eq("com_id",request.getComId());
        queryWrapper.eq("point_id",request.getPointId());
        queryWrapper.eq("meal_no",request.getMealNo());
        queryWrapper.ge("receipt_id",0);
        queryWrapper.groupBy("dishes_id");
        queryWrapper.orderByAsc("dishes_id");
        List<EntityXfGoodListOrg>  listOrgs = this.list(queryWrapper);
        List<DishesIdNumVo>  dishesIdNumVoList =new ArrayList<>();
        for (EntityXfGoodListOrg entityXfGoodListOrg:listOrgs){
            DishesIdNumVo dishesIdNumVo =new DishesIdNumVo();
            dishesIdNumVo.setDishesId(entityXfGoodListOrg.getDishesId());
            dishesIdNumVo.setOrderNumber(entityXfGoodListOrg.getWeightNumber());
            dishesIdNumVoList.add(dishesIdNumVo);
        }
        return dishesIdNumVoList;
    }

    @Override
    public List<GetMealPreReportsXMVo> getMealPreReportsXM(GetMealPreReportsXMRequest request) {
        List<GetMealPreReportsXMVo> allList = new ArrayList<>();
        Long months = DateUtil.betweenMonth(request.getMealDateBegin(),request.getMealDateEnd(),false);
        for (int i = 0; i <= months; i++) {
            String monthValue = DateUtil.format(DateUtil.offset(request.getMealDateBegin(), DateField.MONTH,i),"yyyyMM");
            QueryWrapper<EntityXfGoodListOrg> queryWrapper = new QueryWrapper<>();
            queryWrapper.select("receipt_name,meal_date,point_id,dishes_id, meal_no ,dishes_name,price_mode,dishes_price,sum(weight_number) dishCount");
            queryWrapper.eq("com_id",request.getComId())
                    .between("meal_date",request.getMealDateBegin(),request.getMealDateEnd())
                    .eq(ObjectUtil.isNotEmpty(request.getPointId()),"point_id",request.getPointId())
                    .eq("if_refund",0)
                    .eq(ObjectUtil.isNotEmpty(request.getMerchId()) && 0 < request.getMerchId(),"merch_id",request.getMerchId())
                    .eq("month_value",monthValue)
                    .gt(1==request.getHidFee(),"dishes_price",0)
                    .eq(2==request.getHidFee(),"dishes_price",0)
                    .groupBy("point_id, meal_date,meal_no,dishes_name,price_mode")
            ;
            List<GetMealPreReportsXMVo> list = this.baseMapper.getMealPreReportsXM(queryWrapper);
            allList.addAll(list);

        }
        Map<String,GetMealPreReportsXMVo> mealPreReportsXMVoMap = new HashMap<>();
        List<GetMealPreReportsXMVo> resultList = new ArrayList<>();
        for (GetMealPreReportsXMVo getMealPreReportsXMVo:allList) {
            String mapKey = DateUtil.format(getMealPreReportsXMVo.getMealDate(),"yyyyMMdd")+"_"+getMealPreReportsXMVo.getReceiptName() + "_" + getMealPreReportsXMVo.getDishesName() + "_" + getMealPreReportsXMVo.getPriceMode();
            if(ObjectUtil.isNotEmpty(mealPreReportsXMVoMap.get(mapKey))){
                getMealPreReportsXMVo.setDishCount(getMealPreReportsXMVo.getDishCount()+mealPreReportsXMVoMap.get(mapKey).getDishCount());
            }
            mealPreReportsXMVoMap.put(mapKey,getMealPreReportsXMVo);
        }
        for (Map.Entry<String,GetMealPreReportsXMVo> getMealPreReportsXMVoEntry: mealPreReportsXMVoMap.entrySet()){
            resultList.add(getMealPreReportsXMVoEntry.getValue());
        }
        return resultList.stream().sorted(Comparator.comparing(GetMealPreReportsXMVo::getMealDate)).collect(Collectors.toList());
    }

    @Override
    public List<GetMealSendReportsXMByOneVo> getMealSendReportsXMByOne(GetMealSendReportsXMByOneRequest request) {
        List<GetMealSendReportsXMByOneVo> allList = new ArrayList<>();
        Long months = DateUtil.betweenMonth(request.getMealDateBegin(),request.getMealDateEnd(),false);
        for (int i = 0; i <= months; i++) {
            String monthValue = DateUtil.format(DateUtil.offset(request.getMealDateBegin(), DateField.MONTH,i),"yyyyMM");
            QueryWrapper<EntityXfGoodListOrg> queryWrapper = new QueryWrapper<>();
            queryWrapper.select("receipt_name,receipt_id,meal_date,point_id,dishes_id, meal_no ,dishes_name,price_mode,dishes_price,sum(weight_number) dishCount");
            queryWrapper.eq("com_id",request.getComId())
                    .between("meal_date",DateUtil.formatDate(request.getMealDateBegin()),DateUtil.formatDate(request.getMealDateEnd()))
                    .eq(ObjectUtil.isNotEmpty(request.getPointId()),"point_id",request.getPointId())
                    .eq("if_refund",0)
                    .eq(ObjectUtil.isNotEmpty(request.getMerchId()) && 0 < request.getMerchId(),"merch_id",request.getMerchId())
                    .eq("month_value",monthValue)
                    .like(ObjectUtil.isNotEmpty(request.getReceiptName()),"receipt_name",request.getReceiptName())
                    .gt(1==request.getHidFee(),"dishes_price",0)
                    .eq(2==request.getHidFee(),"dishes_price",0)
                    .groupBy("receipt_name,meal_date,meal_no, dishes_name,price_mode")
            ;
            List<GetMealSendReportsXMByOneVo> list = this.baseMapper.GetMealSendReportsXMByOne(queryWrapper);
            allList.addAll(list);

        }
        Map<String,GetMealSendReportsXMByOneVo> mealPreReportsXMVoMap = new HashMap<>();
        List<GetMealSendReportsXMByOneVo> resultList = new ArrayList<>();
        for (GetMealSendReportsXMByOneVo getMealPreReportsXMVo:allList) {
            String mapKey = DateUtil.format(getMealPreReportsXMVo.getMealDate(),"yyyyMMdd")+"_"+getMealPreReportsXMVo.getReceiptName() + "_" + getMealPreReportsXMVo.getDishesName() + "_" + getMealPreReportsXMVo.getPriceMode();
            if(ObjectUtil.isNotEmpty(mealPreReportsXMVoMap.get(mapKey))){
                getMealPreReportsXMVo.setDishCount(getMealPreReportsXMVo.getDishCount()+mealPreReportsXMVoMap.get(mapKey).getDishCount());
            }
            mealPreReportsXMVoMap.put(mapKey,getMealPreReportsXMVo);
        }
        for (Map.Entry<String,GetMealSendReportsXMByOneVo> getMealPreReportsXMVoEntry: mealPreReportsXMVoMap.entrySet()){
            resultList.add(getMealPreReportsXMVoEntry.getValue());
        }

        return resultList.stream().sorted(Comparator.comparing(GetMealSendReportsXMByOneVo::getMealDate)).collect(Collectors.toList());
    }

    @Override
    public List<GetMealSendReportsXMByTwoVo> getMealSendReportsXMByTwo(GetMealSendReportsXMByTwoRequest request) {
        String monthValue = DateUtil.format(request.getMealDate(),"yyyyMM");
        QueryWrapper<EntityXfGoodListOrg> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("receipt_name,receipt_id,meal_date,point_id,dishes_id, meal_no ,dishes_name,price_mode,dishes_price,sum(weight_number) dishCount");
        queryWrapper.eq("com_id",request.getComId())
                .eq("meal_date",DateUtil.formatDate(request.getMealDate()))
                .eq(ObjectUtil.isNotEmpty(request.getMealNo()),"meal_no",request.getMealNo())
                .eq(ObjectUtil.isNotEmpty(request.getMerchId()) && 0 < request.getMerchId(),"merch_id",request.getMerchId())
                .eq(ObjectUtil.isNotEmpty(request.getPointId()),"point_id",request.getPointId())
                .eq("if_refund",0)
                .eq("month_value",monthValue)
                .like(ObjectUtil.isNotEmpty(request.getReceiptName()),"receipt_name",request.getReceiptName())
                .gt(1==request.getHidFee(),"dishes_price",0)
                .eq(2==request.getHidFee(),"dishes_price",0)
                .groupBy("receipt_name,dishes_name,price_mode")
        ;
        return this.baseMapper.GetMealSendReportsXMByTwo(queryWrapper);
    }

    //    @Override
//    public List<GetPointMealPreVo> getPointMealPre(GetPointMealPreReportsRequest request) throws Exception {
//        String start = request.getStartTime().substring(0, 7).replace("-", "");
//        String end = request.getEndTime().substring(0, 7).replace("-", "");
//        List<String> monthValues = DateUtils.getMonthBetween(start, end);
//        List<GetPointMealPreVo> pointMealPreList = new ArrayList<>();
//        String database = "01";
//        if (500 <= request.getComId()) {
//            database = "02";
//        }
//        for (String monthValue : monthValues) {
//            List<GetPointMealPreVo> pointMealPres = xfGoodListOrgMapper.getPointMealPre(request.getComId(), request.getPointId(), request.getStartTime(), request.getEndTime(), monthValue, database);
//            pointMealPreList.addAll(pointMealPres);
//        }
//        return pointMealPreList;
//    }

//    @Override
//    public List<GetPointMealSendVo> getPointMealSend(GetPointMealSendReportsRequest request) throws Exception {
//        String start = request.getStartTime().substring(0, 7).replace("-", "");
//        String end = request.getEndTime().substring(0, 7).replace("-", "");
//        List<String> monthValues = DateUtils.getMonthBetween(start, end);
//        List<GetPointMealSendVo> pointMealSendList = new ArrayList<>();
//        String database = "01";
//        if (500 <= request.getComId()) {
//            database = "02";
//        }
//        for (String monthValue : monthValues) {
//            List<GetPointMealSendVo> pointMealSends = xfGoodListOrgMapper.getPointMealSend(request.getComId(), request.getPointId(), request.getStartTime(), request.getEndTime(), request.getReceiptId(), request.getReceiptName(),  monthValue, database);
//            pointMealSendList.addAll(pointMealSends);
//        }
//        return pointMealSendList;
//
//    }

    @Override
    public Result getPerVideoList(GetPerVideoListRequest request) {

        String month = DateUtil.format(request.getMonth(), "yyyyMM");
        QueryWrapper<GetPerVideoListVo> queryWrapper = new QueryWrapper<>();
        queryWrapper
                .eq("r.month_value",month)
                .eq("g.month_value",month)
                .eq(ObjectUtil.isNotEmpty(request.getComId()) && !request.getComId().equals(-1L),"r.com_id",request.getComId())
                .eq(ObjectUtil.isNotEmpty(request.getPId()) && !request.getPId().equals(-1L),"r.p_id",request.getPId())
                .eq("r.sub_account","1")
                .orderByDesc("r.sub_account")
        ;

        Map<String,Object> map = new HashMap<>();
        Integer total = 0;
        List<GetPerVideoListVo> listVoList;
        if((ObjectUtil.isEmpty(request.getPage()) || request.getPage().equals(-1)) || (ObjectUtil.isEmpty(request.getSize()) || request.getSize().equals(-1)) ){
            listVoList = this.baseMapper.getPerVideoList(queryWrapper);
            total = listVoList.size();

        }else{
            IPage<GetPerVideoListVo> page = this.baseMapper.getPerVideoPage(new Page<>(request.getPage(), request.getSize()),queryWrapper);
            total = (int)page.getTotal();
            listVoList = page.getRecords();
        }
        listVoList.forEach(getPerVideoListVo -> {
            getPerVideoListVo.setOpType(OpTypeEnum.getName(Integer.parseInt(getPerVideoListVo.getOpType())));
            getPerVideoListVo.setOpTypeDiff(OpTypeDiffEnum.getName(Integer.parseInt(getPerVideoListVo.getOpTypeDiff())));
            getPerVideoListVo.setConsState(ConsStateEnum.getValueByKey(Integer.parseInt(getPerVideoListVo.getConsState())));
        });
        map.put("total",total);
        map.put("list",listVoList);
        return ResultUtil.success(map);
    }

    @Override
    public Boolean updateChangeDishes(UpdateChangeDishesRequest request) {
        String month = request.getMonth();
        EntityXfGoodListOrg entityXfGoodListOrg = new EntityXfGoodListOrg();
        entityXfGoodListOrg.setMonthValue(month);
        entityXfGoodListOrg.setDishesId(request.getDishesId());
        entityXfGoodListOrg.setDishesName(request.getDishesName());
        QueryWrapper<EntityXfGoodListOrg> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("com_id",request.getComId()).eq("order_no",request.getOrderNo()).eq("month_value",month);
        return this.update(entityXfGoodListOrg, queryWrapper);
    }
}
